package com.whynot.frame.basic.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 
 * <ol>封装线程处理相关工具类，方便开发人员使用线程
 * <li>{@link  }</li>
 * 
 * </ol>
 * @see
 * @author wanghui 
 * @since 1.0
 * @2016年5月6日
 *
 */
public class ThreadUtils {
	/**
	* Logger for this class
	*/
	private static final Logger logger = LoggerFactory.getLogger(ThreadUtils.class);

	public static void waitingShortTime() {
		sleep(100L);
	}

	/**
	 * 暂停当前线程的执行
	 * @param millis
	 */
	public static void sleep(final long millis) {
		try {
			Thread.sleep(millis);
		} catch (final InterruptedException ex) {
			Thread.currentThread().interrupt();
		}
	}

	/**
	 * 如果某个请求需要调用多个外部请求， 可以将每个外部请求都独立到一个线程中进行处理;
	 *  最后等每个线程处理完，再返回整体信息
	 * 
	 * @param jobs
	 */
	public static void executeJobByThreads(Job... jobs) {
		final CountDownLatch latch = new CountDownLatch(jobs.length);
		ExecutorService executorService = getExecutorService();
		for (final Job job : jobs) {
			executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                    	job.process();
                    } finally {
                    	logger.debug("job finish");
                    	latch.countDown();
                    }
                }
            });
		}
		latchAwait(latch);
		logger.debug("all job finish");
	}

	public static void latchAwait(final CountDownLatch latch) {
		try {
			latch.await();
		} catch (final InterruptedException ex) {
			Thread.currentThread().interrupt();
		}
	}

	public static ExecutorService getExecutorService() {
		return Executors.newCachedThreadPool();
	}
	
	public static interface Job{
		 void process() ;
	}

	/**
	 * executeThreads方法使用案例
	 * @param args
	 */
	public static void main(String[] args) {
		String[] ls = new String[] { "api1", "api2", "api3" };
		final List<Object> lsList = new ArrayList<Object>();
		
		//构造多线程处理请求，
		List<Job> jobs = new ArrayList<Job>();
		for (int i = 0; i < ls.length; i++) {
			final String str = ls[i];
			jobs.add(new Job() {
				@Override
				public void process() {
					//
					System.out.println(str);
					// DO SOME THING
					String result = str;
					lsList.add(result);
				}
			});
		}
		//多线程请求
		ThreadUtils.executeJobByThreads(jobs.toArray( new Job[] {}));
		//加工各个线程处理的合集lsList
		System.out.println(lsList);
	}

}
